package com.gjzhao.fmmall.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @Description: Token 工具类: 封装生成token与解析token的方法
 * @Author: gjzhao
 * @Date Created in 2022-01-01 8:51 上午
 */
@Component
public class JwtUtil {

    private Logger logger = LoggerFactory.getLogger(getClass());

    /** 密钥 key */
    //TODO 将参数放在配置文件中
    private String secretKey = "gjzhao";

    /** 过期时间：默认24小时 */
    private long ttl = 24 * 60 * 60;


    /**
     * 生成 token
     *
     * @param id      唯一id
     * @param subject token主题
     * @return
     */
    public String getToken(String id, String subject, String role) {

        logger.info("-----------开始生成token----------");

        //生成token一并返回给前端
        JwtBuilder builder = Jwts.builder();

        Map<String, Object> map = new HashMap<>();
        map.put("key", "value");

        String token = builder.setId(id) //唯一id
                              .setSubject(subject) //token主题
                              .setIssuedAt(new Date()) //生成时间
                              .claim("roles", role) //权限控制
                              //.setClaims(map) //可传入用户角色权限相关信息 注意如果加上了参数，获取不到subject部分
                              .setExpiration(new Date(System.currentTimeMillis() + ttl * 1000)) //过期时间 TODO 防止过期时间出现负数，可以加一层判断
                              .signWith(SignatureAlgorithm.HS256, secretKey) //密钥与算法
                              .compact();

        logger.info("-----------token生成完成:{}----------", token);

        return token;
    }

    /**
     * 解析token
     *
     * @param token
     * @return
     */
    public Claims parseToken(String token) {

        logger.info("-----------开始解析token:{}----------", token);

        Claims claims = null;

        try {

            JwtParser parser = Jwts.parser();
            parser.setSigningKey(secretKey);//设置密钥key
            Jws<Claims> claimsJws = parser.parseClaimsJws(token);
            claims = claimsJws.getBody();

            logger.info("-----------解析token完成:{}----------", claims);

        } catch (Exception e) {
            e.printStackTrace();
            logger.info("-----------解析token失败:{}----------", claims);
        }

        return claims;
    }


    /**
     * 获取token中的用户名
     *
     * @param token
     * @return
     */
    public String getUserNameFromToken(String token) {

        String username;

        try {
            Claims claims = this.parseToken(token);
            username = claims.getSubject();
        } catch (Exception e) {
            e.printStackTrace();
            username = null;
        }

        return username;
    }


    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public long getTtl() {
        return ttl;
    }

    public void setTtl(long ttl) {
        this.ttl = ttl;
    }
}
